using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using GameFrameWork;
using UnityEngine;

/// <summary>
/// 机枪射手攻击策略 - 连续发射多发子弹，高频率输出伤害
/// </summary>
public class GatlingAttackStrategy : AttackStrategyBase
{
    private GatlingSkillData m_GatlingSkillData;
    private CancellationTokenSource m_CancellationTokenSource;

    public GatlingAttackStrategy(SkillData data)
    {
        AttackData = data;
        if (data is GatlingSkillData gatlingData)
        {
            m_GatlingSkillData = gatlingData;
        }
    }

    public override void Execute(Entity target)
    {
        base.Execute(target);

        if (target == null)
        {
            Logger.LogWarning("GatlingAttackStrategy", $"{Owner?.name} 攻击目标无效");
            return;
        }

        if (AttackData == null || AttackData.BulletData == null)
        {
            Logger.LogError("GatlingAttackStrategy", $"{Owner?.name} 缺少子弹数据");
            return;
        }

        if (m_GatlingSkillData == null)
        {
            Logger.LogError("GatlingAttackStrategy", $"{Owner?.name} 技能数据不是 GatlingSkillData 类型");
            return;
        }

        // 取消之前的连续发射任务（如果存在）
        Cancel();

        // 开始连续发射
        StartBurstFire(target).Forget();
    }

    /// <summary>
    /// 开始连续发射
    /// </summary>
    private async UniTaskVoid StartBurstFire(Entity target)
    {
        // 创建取消令牌
        m_CancellationTokenSource = new CancellationTokenSource();
        var token = m_CancellationTokenSource.Token;

        try
        {
            int burstCount = m_GatlingSkillData.BurstCount;
            float burstInterval = m_GatlingSkillData.BurstInterval;

            Logger.Log("GatlingAttackStrategy", $"{Owner?.name} 开始连续发射，共 {burstCount} 发，间隔 {burstInterval} 秒");

            // 连续发射
            for (int i = 0; i < burstCount; i++)
            {
                // 检查是否被取消或植物已死亡
                if (token.IsCancellationRequested || !CheckCondition())
                {
                    Logger.Log("GatlingAttackStrategy", $"{Owner?.name} 连续发射被中断");
                    break;
                }

                // 发射子弹
                FireSingleBullet(target);

                // 如果不是最后一发，等待间隔时间
                if (i < burstCount - 1)
                {
                    await UniTask.Delay(TimeSpan.FromSeconds(burstInterval), cancellationToken: token);
                }
            }

            Logger.Log("GatlingAttackStrategy", $"{Owner?.name} 连续发射完成");
        }
        catch (System.OperationCanceledException)
        {
            Logger.Log("GatlingAttackStrategy", $"{Owner?.name} 连续发射被取消");
        }
        finally
        {
            IsExecuting = false;
        }
    }

    /// <summary>
    /// 发射单发子弹
    /// </summary>
    private void FireSingleBullet(Entity target)
    {
        if (Owner == null || AttackData == null || AttackData.BulletData == null)
        {
            return;
        }

        var bulletData = AttackData.BulletData;
        var bullet = BulletPool.Instance.GetBullet(bulletData);

        if (bullet == null)
        {
            Logger.LogError("GatlingAttackStrategy", $"无法获取子弹：{bulletData.BulletType}");
            return;
        }

        // 设置子弹位置
        Vector3 startPos = Owner.transform.position;
        if (bulletData.OffVec3 != Vector3.zero)
        {
            startPos += bulletData.OffVec3;
        }
        bullet.transform.position = startPos;

        // 创建移动策略
        var movement = MoveStrategyFactory.Create(bulletData.MoveData);
        bullet.Initialize(
            owner: Owner,
            movement: movement
        );

        // 播放射击动画（可选，避免重复播放）
        // AnimateShooting();
    }

    public override void Cancel()
    {
        base.Cancel();

        // 取消连续发射任务
        if (m_CancellationTokenSource != null && !m_CancellationTokenSource.IsCancellationRequested)
        {
            m_CancellationTokenSource.Cancel();
            m_CancellationTokenSource.Dispose();
            m_CancellationTokenSource = null;
        }
    }

    public override bool CheckCondition()
    {
        return base.CheckCondition() &&
               AttackData != null &&
               AttackData.BulletData != null &&
               m_GatlingSkillData != null;
    }
}

